package com.zheng.api.server.service.mq.pay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zheng.api.server.service.base.pay.Base4TransOrderService;
import com.zheng.api.server.service.base.pay.BaseNotify4MchTrans;
import com.zheng.api.server.service.base.pay.PayChannel4AliService;
import com.zheng.api.server.service.base.pay.PayChannel4WxService;
import com.zheng.common.constant.MqConstant;
import com.zheng.common.constant.PayConstant;
import com.zheng.common.util.RpcUtil;
import com.zheng.pay.dao.model.PayTransOrder;
import com.zheng.pay.dao.model.PayTransOrderExample;
import com.zheng.pay.rpc.api.*;
import org.apache.activemq.ScheduledMessage;
import org.apache.activemq.command.ActiveMQQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;

import javax.jms.*;
import javax.jms.Queue;
import java.util.*;

/**
 * @Description: 业务通知MQ实现
 * @author lvb
 * @date 2017-10-30
 * @version V1.0
 * @Copyright:
 */
@Service
public class Mq4TransNotify extends Base4TransOrderService {

    private Queue transNotifyQueue = new ActiveMQQueue(MqConstant.ZHENG_SERVER_QUEUE_PAY_NOTIFY_TRANS_NAME);
    @Autowired
    private JmsTemplate jmsQueueTemplate;
    @Autowired
    PayIapReceiptService payIapReceiptService;
    @Autowired
    PayMchNotifyService payMchNotifyService;
    @Autowired
    PayPayOrderService payPayOrderService;
    @Autowired
    PayRefundOrderService payRefundOrderService;
    @Autowired
    PayTransOrderService payTransOrderService;
    @Autowired
    PayChannel4AliService payChannel4AliService;
    @Autowired
    PayChannel4WxService payChannel4WxService;
    @Autowired
    BaseNotify4MchTrans baseNotify4MchTrans;
    
    private static final Logger LOGGER = LoggerFactory.getLogger(Mq4TransNotify.class);

    public void send(String msg) {
        LOGGER.info("发送MQ消息:msg={}", msg);
        this.jmsQueueTemplate.convertAndSend(this.transNotifyQueue, msg);
    }

    /**
     * 发送延迟消息
     * @param msg
     * @param delay
     */
    public void send(final String msg, final long delay) {
        LOGGER.info("发送MQ延时消息:msg={},delay={}", msg, delay);
        jmsQueueTemplate.send(this.transNotifyQueue, new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                TextMessage tm = session.createTextMessage(msg);
                tm.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);
                tm.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, 1*1000);
                tm.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, 1);
                return tm;
            }
        });
    }

    @JmsListener(destination = MqConstant.ZHENG_SERVER_QUEUE_PAY_NOTIFY_TRANS_NAME)
    public void receive(String msg) {
        LOGGER.info("处理转账任务.msg={}", msg);
        JSONObject msgObj = JSON.parseObject(msg);
        String transOrderId = msgObj.getString("transOrderId");
        String channelName = msgObj.getString("channelName");

        PayTransOrderExample transExample = new PayTransOrderExample();
        PayTransOrderExample.Criteria transCriteria = transExample.createCriteria();
        transCriteria.andTransorderidEqualTo(transOrderId);
        PayTransOrder transOrder = payTransOrderService.selectFirstByExample(transExample);
        if(transOrder == null) {
            LOGGER.warn("查询转账订单为空,不能转账.transOrderId={}", transOrderId);
            return;
        }
        if(transOrder.getStatus() != PayConstant.TRANS_STATUS_INIT) {
            LOGGER.warn("转账状态不是初始({})或失败({}),不能转账.transOrderId={}", PayConstant.TRANS_STATUS_INIT, PayConstant.TRANS_STATUS_FAIL, transOrderId);
            return;
        }

        PayTransOrder updateTransOrder = new PayTransOrder();
        updateTransOrder.setStatus(PayConstant.TRANS_STATUS_TRANING);
        updateTransOrder.setTranssucctime(new Date());
        PayTransOrderExample example = new PayTransOrderExample();
        PayTransOrderExample.Criteria criteria = example.createCriteria();
        criteria.andTransorderidEqualTo(transOrderId);
        List<Byte> list = new LinkedList<>();
        list.add(PayConstant.TRANS_STATUS_INIT);
        list.add(PayConstant.TRANS_STATUS_FAIL);
        criteria.andStatusIn(list);
        int result = payTransOrderService.updateByExampleSelective(updateTransOrder, example);

        if(result != 1) {
            LOGGER.warn("更改转账为转账中({})失败,不能转账.transOrderId={}", PayConstant.TRANS_STATUS_TRANING, transOrderId);
            return;
        }
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("transOrder", transOrder);
        String jsonParam = RpcUtil.createBaseParam(paramMap);
        Map resultMap;
        if(PayConstant.CHANNEL_NAME_WX.equalsIgnoreCase(channelName)) {
            resultMap = payChannel4WxService.doWxTransReq(jsonParam);
        }else if(PayConstant.CHANNEL_NAME_ALIPAY.equalsIgnoreCase(channelName)) {
            resultMap = payChannel4AliService.doAliTransReq(jsonParam);
        }else {
            LOGGER.warn("不支持的转账渠道,停止转账处理.transOrderId={},channelName={}", transOrderId, channelName);
            return;
        }
        if(!RpcUtil.isSuccess(resultMap)) {
            LOGGER.warn("发起转账返回异常,停止转账处理.transOrderId={}", transOrderId);
            return;
        }
        Map bizResult = (Map) resultMap.get("bizResult");
        Boolean isSuccess = false;
        if(bizResult.get("isSuccess") != null) isSuccess = Boolean.parseBoolean(bizResult.get("isSuccess").toString());
        if(isSuccess) {
            // 更新转账状态为成功
            String channelOrderNo = bizResult.get("channelOrderNo") == null ? "" : bizResult.get("channelOrderNo").toString();
            result = baseUpdateStatus4Success(transOrderId, channelOrderNo);
            LOGGER.info("更新转账订单状态为成功({}),transOrderId={},返回结果:{}", PayConstant.TRANS_STATUS_SUCCESS, transOrderId, result);
            // 发送商户通知
            baseNotify4MchTrans.doNotify(transOrder, true);
        }else {
            // 更新转账状态为成功
            String channelErrCode = bizResult.get("channelErrCode") == null ? "" : bizResult.get("channelErrCode").toString();
            String channelErrMsg = bizResult.get("channelErrMsg") == null ? "" : bizResult.get("channelErrMsg").toString();
            result = baseUpdateStatus4Fail(transOrderId, channelErrCode, channelErrMsg);
            LOGGER.info("更新转账订单状态为失败({}),transOrderId={},返回结果:{}", PayConstant.TRANS_STATUS_FAIL, transOrderId, result);
            // 发送商户通知
            baseNotify4MchTrans.doNotify(transOrder, true);
        }

    }
}
